package com.xinxin.o2o.util;

import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.imageio.ImageIO;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author 史鑫鑫
 * @date 2019-08-13 22:15
 */
public class ImageUtil {
    private static String basePath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
    private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss");
    private static final Random RANDOM = new Random();
    private static Logger logger = LoggerFactory.getLogger(ImageUtil.class);

    /**
     * 将CommonsMultipartFile类转换成File类
     *
     * @param commonsMultipartFile CommonsMultipartFile类
     * @return File
     */
    public static File transferCommonsMultipartFileToFile(CommonsMultipartFile commonsMultipartFile) {
        File file = new File(Objects.requireNonNull(commonsMultipartFile.getOriginalFilename()));
        try {
            commonsMultipartFile.transferTo(file);
        } catch (IOException e) {
            logger.error(e.toString());
            e.printStackTrace();
        }
        return file;
    }

    /**
     * 处理缩略图，并返回新生成图片的相对值路径
     *
     * @param thumbnail  文件
     * @param targetAddr 目标地址
     * @return 新生成图片的相对值路径
     */
    public static String generateThumbnail(InputStream thumbnail, String targetAddr, String fileName) throws IOException {
        // 获取文件随机名
        String realFileName = getRandomFileName();
        // 获取文件扩展名
        String extension = getFileExtension(fileName);
        // 创建文件路径
        makeDirPath(targetAddr);
        // 获取相对路径
        String relativeAddr = targetAddr + realFileName + extension;
        logger.debug("current relative addr is : " + relativeAddr);
        // 组合出的文件路径
        File dest = new File(PathUtil.getImgBasePath() + relativeAddr);
        logger.debug("current complete addr is : " + PathUtil.getImgBasePath() + relativeAddr);
        Thumbnails.of(thumbnail)
                .size(200, 200)
                .watermark(Positions.BOTTOM_RIGHT,
                        ImageIO.read(new File(basePath + "/watermark.jpg")),
                        0.25f)
                .outputQuality(0.8f)
                .toFile(dest);
        return relativeAddr;
    }

    /**
     * 生成随机文件名,当前年月日小时分钟秒数+五位随机数
     *
     * @return 随机文件名
     */
    public static String getRandomFileName() {
        // 获取随机五位数
        int ranNum = RANDOM.nextInt(89999) + 10000;
        String nowTimeStr = SIMPLE_DATE_FORMAT.format(new Date());
        return nowTimeStr + ranNum;
    }

    /**
     * 获取文件扩展名
     *
     * @param fileName 文件名
     * @return 文件扩展名
     */
    private static String getFileExtension(String fileName) {
        return fileName.substring(fileName.lastIndexOf("."));
    }

    /**
     * 创建目标路径所涉及到的目录，即/home/work/xiaoze/xxx.jpg
     *
     * @param targetAddr 文件路径
     */
    private static void makeDirPath(String targetAddr) {
        String realFileParentPath = PathUtil.getImgBasePath() + targetAddr;
        File dirPath = new File(realFileParentPath);
        if (!dirPath.exists()) {
            boolean res = dirPath.mkdirs();
            if (!res) {
                throw new RuntimeException("创建文件夹失败");
            }
        }
    }

    public static void inputStreamToFile(InputStream inputStream, File file) {
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[1024];
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                fileOutputStream.write(buffer, 0, bytesRead);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("调用inputStreamToFile产生异常：" + e.getMessage());
        }
        try {
            fileOutputStream.close();
            inputStream.close();
        } catch (IOException e) {
            throw new RuntimeException("inputStreamToFile关闭io产生异常" + e.getMessage());
        }
    }

    /**
     * storePath是文件的路径还是目录的路径
     * 如果storePath是文件路径则删除该文件
     * 如果storePath是目录路径则删除该目录下的所有文件
     *
     * @param storePath 原路径
     */
    public static void deleteFileOrPath(String storePath) {
        File fileOrPath = new File(PathUtil.getImgBasePath() + storePath);
        if (fileOrPath.exists()) {
            if (fileOrPath.isDirectory()) {
                File[] files = fileOrPath.listFiles();
                if (files != null) {
                    for (File file : files) {
                        file.delete();
                    }
                }
            }
            fileOrPath.delete();
        }
    }

    public static List<String> generateNormalImgs(List<MultipartFile> imgs, String targetAddr) {
        int count = 0;
        List<String> relativeAddrList = new ArrayList<String>();
        if (imgs != null && imgs.size() > 0) {
            makeDirPath(targetAddr);
            for (MultipartFile img : imgs) {
                String realFileName = FileUtil.getRandomFileName();
                String extension = getFileExtension(Objects.requireNonNull(img.getOriginalFilename()));
                String relativeAddr = targetAddr + realFileName + count + extension;
                File dest = new File(FileUtil.getImgBasePath() + relativeAddr);
                count++;
                try {
                    Thumbnails.of(img.getInputStream()).size(600, 300).outputQuality(0.5f).toFile(dest);
                } catch (IOException e) {
                    throw new RuntimeException("创建图片失败：" + e.toString());
                }
                relativeAddrList.add(relativeAddr);
            }
        }
        return relativeAddrList;
    }

    public static void main(String[] args) throws IOException {
        Thumbnails.of(new File("D:\\Other\\Picture\\人物\\ding.jpg")).size(413,413).toFile(new File("D:\\Other\\Picture\\人物\\ding2.jpg"));
    }
}
